特定のセキュリティグループ・ポートが変更されたことをカスタマイズした日本語メールで通知してみた
こんにちは!AWS事業本部のおつまみです。
みなさん、特定のセキュリティグループ・ポートが変更されたことを検知して、メール通知してほしいなぁと思ったことはありますか?私はあります。
以前こちらのブログにて、特定のセキュリティグループが変更されたことをカスタマイズした日本語メールで通知する方法をご紹介しました。
今回上記のブログで展開したテンプレートにて、以下の追加要望を受けました。
- 特定ポート(SSH・RDP)の変更のみ通知したい
- セキュリティグループをパラメータで指定できるようにして欲しい。
この要望に沿って、CloudFormationテンプレートを修正したので、ご紹介します!
メール通知内容は前回と同様な文面となります。
構成図
今回構築する構成は前回から変更ありません。
前提として、CloudTrailが既に有効化されている環境で構築します。
セキュリティグループを変更してから、ユーザーにメール通知するまでの流れ
①Amazon EventBridge:セキュリティグループの変更イベントを検知。EventBridgeの入力トランスフォーマーで、メールの件名と本文を設定。
②AWS StepFunctions:Amazon SNS publish API を呼び出し、件名と本文を指定して通知。※SNSをEventBridgeのターゲットに直接指定するとメール件名の指定ができません。
③Amazon SNS:指定したアドレス宛にメール通知。
CloudFormationテンプレートを準備
テンプレート内容は以下の通りです。
テンプレート
AWSTemplateFormatVersion: '2010-09-09'
Description: "create Security group change notification"
# ------------------------------------------------------------#
# Input Parameters
# ------------------------------------------------------------#
Parameters:
PJPrefix:
Type: String
SNSTopicName:
Type: String
Default: SecurityGroup_Change_Alarm
Email:
Type: String
Default: email_address
TargetSecurityGroupIds:
Type: CommaDelimitedList
Description: If there are multiple target security groups, please enter them separated by [,]
Default: sg-1234567890abcdef0
Resources:
# ------------------------------------------------------------#
# SNS Topic
# ------------------------------------------------------------#
SNSTopic:
Type: "AWS::SNS::Topic"
Properties:
TopicName: !Ref SNSTopicName
Tags:
-
Key: "Name"
Value: !Sub ${PJPrefix}-${SNSTopicName}
# ------------------------------------------------------------#
# SNS Subscription
# ------------------------------------------------------------#
Subscription:
Type: "AWS::SNS::Subscription"
Properties:
TopicArn: !Ref SNSTopic
Endpoint: !Ref Email
Protocol: "email"
# ------------------------------------------------------------#
# SNS TopicPolicy
# ------------------------------------------------------------#
EventTopicPolicy:
Type: 'AWS::SNS::TopicPolicy'
Properties:
PolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: events.amazonaws.com
Action: 'sns:Publish'
Resource: '*'
Topics:
- !Ref SNSTopic
# ------------------------------------------------------------#
# StepFunction メール本文カスタマイズ用
# ------------------------------------------------------------#
SNSStateMachine:
Type: "AWS::StepFunctions::StateMachine"
Properties:
DefinitionString: !Sub |-
{
"StartAt": "PublishSns",
"States": {
"PublishSns": {
"Type": "Task",
"Resource": "arn:aws:states:::sns:publish",
"Parameters": {
"TopicArn": "arn:aws:sns:${AWS::Region}:${AWS::AccountId}:${SNSTopicName}",
"Message.$": "$.message",
"Subject.$": "$.subject"
},
"End": true
}
}
}
RoleArn: !GetAtt PublishRole.Arn
# ------------------------------------------------------------#
# IAMロール (StepFunction用)
# ------------------------------------------------------------#
PublishRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service:
- states.amazonaws.com
Action: "sts:AssumeRole"
Path: "/"
Policies:
- PolicyName: SNSPublish
PolicyDocument:
Statement:
- Effect: Allow
Resource:
- !Ref SNSTopic
Action:
- sns:Publish
StateMachineExecuteRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service:
- events.amazonaws.com
Action: "sts:AssumeRole"
Path: "/"
Policies:
- PolicyName: StateMachineExecute
PolicyDocument:
Statement:
- Effect: Allow
Resource:
- !Ref SNSStateMachine
Action:
- states:StartExecution
# ------------------------------------------------------------#
# EventBridge Rule
# ------------------------------------------------------------#
EventBridgeRule:
Type: AWS::Events::Rule
DependsOn: SNSTopic
Properties:
Description: !Ref SNSTopicName
EventBusName: default
EventPattern:
Fn::Sub:
- |-
{
"source": ["aws.ec2"],
"detail-type": ["AWS API Call via CloudTrail"],
"detail": {
"eventSource": ["ec2.amazonaws.com"],
"eventName": ["AuthorizeSecurityGroupIngress", "AuthorizeSecurityGroupEgress", "RevokeSecurityGroupIngress", "RevokeSecurityGroupEgress"],
"requestParameters": {
"groupId": ${SGIds},
"ipPermissions": {
"items": {
"fromPort": [22, 3389]
}
}
}
}
}
- SGIds: !Join
- ''
- - '["'
- !Join
- '","'
- !Ref TargetSecurityGroupIds
- '"]'
Name: !Ref SNSTopicName
Targets:
- Arn: !Ref SNSStateMachine
Id: step-function
RoleArn: !GetAtt StateMachineExecuteRole.Arn
InputTransformer:
InputPathsMap:
"Account" : "$.account"
"SecuritygroupId" : "$.detail.requestParameters.groupId"
"eventId" : "$.detail.eventID"
"time" : "$.time"
"userName" : "$.detail.userIdentity.sessionContext.sessionIssuer.userName"
"value" : "$.detail"
InputTemplate: |
{
"subject": "セキュリティグループのRDP/SSH変更通知",
"message": "セキュリティグループ \"<SecuritygroupId>\" が変更されたことを検知しました。 \n詳細は次のとおりです。 \nAccount ID : \"<Account>\" \n発生時間 : \"<time> \"(UTC) \n変更ユーザー名 : \"<userName>\" \nセキュリティグループID : \"<SecuritygroupId>\" \nCloudTrailイベントID : \"<eventId>\" \n\nセキュリティグループの確認方法 \nEC2コンソール画面の左メニュータグより「セキュリティグループ」を選択します。\n検索ウィンドウで「セキュリティグループID」を入力し、セキュリティグループが正しいことを確認してください。 \n\nCloudTrailイベント履歴の確認方法 \nCloudTrailコンソール画面の左メニュータグより「イベント履歴」を選択します。 \n検索ウィンドウで[イベントID]を選択し、「CloudTrailイベントID」入力します。イベント詳細が確認できます。"
}
前回構成からの変更点
前回の構成から以下のような変更を行いました。
-
TargetSecurityGroupIds パラメータの追加:
- セキュリティグループをTargetSecurityGroupIds パラメータで指定できるよう変更
- 単一だけでなく、複数のセキュリティグループIDをカンマ区切りで指定可能
-
EventBridgeRule EventPatternの変更:
- イベントパターンが、指定された特定のセキュリティグループIDに対するRDPまたはSSHの変更のみをマッチングするよう変更
- 参考:EventBridge ルール用のカスタムイベントパターンを作成する | AWS re:Post
-
EventBridgeRule InputTemplateの変更:
- メール通知の件名と本文を特定のセキュリティグループに対する変更であることがわかるよう変更
いざ検証
CloudFromationでデプロイ
パラメータは、以下の値を入れます。
- Email
- SNS通知させたいメールアドレス
- PJPrefix
- プロジェクト名
- SNSTopicName
- SNSのトピック名(デフォルトのままで問題なし)
- TargetSecurityGroupIds
- 監視対象とするセキュリティグループのID、複数指定したい場合はカンマで区切って指定可能
- 例
sg-1234567890abcdef0,sg-0987654321abcdef0
3分ほどでデプロイが完了します。
SNSで設定したメールアドレス宛にサブスクリプションの承認依頼メールが届くため、Confirm subscription
で承認します。
セキュリティグループを変更
指定したセキュリティグループのインバウンドルールにSSHポートのルールを追加します。
変更して数秒後、メール通知が届きました!
今回指定した特定のポート(RDP/SSH)以外は、メール通知がとばないことも確認できました。
最後に
今回は特定のセキュリティグループ・ポートが変更されたことを検知して、メール通知させる方法をご紹介しました。
EventBridgeRuleのEventPatternを変更することで、様々な条件に合わせたイベントを検知可能になります。
ぜひカスタマイズしてお使いください。
最後までお読みいただきありがとうございました! どなたかのお役に立てれば幸いです。
以上、おつまみ(@AWS11077)でした!